package com.afdor.rws.event;

import com.afdor.rws.annotation.extension.SPI;
import com.afdor.rws.event.channel.client.consumer.handler.EventHandler;
import lombok.NonNull;

/**
 * 事件总线定义
 *
 * @author 悭梵
 * @date Created in 2018-08-14 10:22
 */
@SPI("default")
public interface EventBus {

    /**
     * 初始化
     * @return
     */
    EventBus init();

    /**
     * 获取事件源管理器
     *
     * @return
     */
    EventSourceManager getEventSourceManager();

    /**
     * 设置事件源管理器
     *
     * @return
     */
    EventBus setEventSourceManager(@NonNull EventSourceManager eventSourceManager);

    /**
     * 设置事件持久化管理器
     *
     * @return
     */
    EventBus setEventPersistenceManager(@NonNull EventPersistenceManager eventPersistenceManager);

    /**
     * 获取事件持久化管理器
     *
     * @return
     */
    EventPersistenceManager getEventPersistenceManager();

    /**
     * 注册事件处理器
     *
     * @param eventSourceName
     * @param eventHandler
     */
    <T extends EventBus> T registerHandler(@NonNull String eventSourceName, @NonNull EventHandler eventHandler);

    /**
     * 开启一个新事物，多次调用会返回多个不同的值
     *
     * @return 返回事物标识。为使用线程本地变量来存此标识，避免多线程切换带来的问题，可放心使用线程池
     */
    @NonNull
    String newTransaction();

    /**
     * 添加到发送队列事件消息
     *
     * @param event
     * @param transactionId 事物标识
     */
    <T extends EventBus> T addEvent(@NonNull String transactionId, @NonNull Event event) throws IllegalAccessException;

    /**
     * 将添加到队列中的事件统一提交
     *
     * @param transactionId 事物标识
     * @return
     */
    void commit(@NonNull String transactionId) throws Exception;

    /**
     * 将添加到队列中的事件统一回滚
     *
     * @param transactionId 事物标识
     */
    void rollback(@NonNull String transactionId) throws Exception;

    /**
     * 发送并提交事件消息
     *
     * @param event
     */
    <T extends EventBus> T sendAndCommitEvent(@NonNull Event event) throws Exception;
}
